package www.wmx.com.xssc.util;

import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import www.wmx.com.xssc.domain.doc.fj.RbtScfjMb;
import www.wmx.com.xssc.domain.doc.fj.ZtComUploadFile;
import www.wmx.com.xssc.domain.doc.fj.ZtComUploadFileOrigin;
import www.wmx.com.xssc.domain.doc.jcyjj.RbtKjjlJcyjjFjxx;
import www.wmx.com.xssc.domain.doc.jsfmj.RbtKjjlJsfmjFjxx;
import www.wmx.com.xssc.domain.doc.kjjbj.RbtKjjlKjjbjFjxx;
import www.wmx.com.xssc.domain.mb.RbtKjjlMbJcyjRank;
import www.wmx.com.xssc.domain.mb.RbtKjjlMbJcyjj;
import www.wmx.com.xssc.domain.mb.RbtKjjlMbTy;
import www.wmx.com.xssc.domain.vo.WcryShortXM;
import www.wmx.com.xssc.domain.vo.extract.BaseMatchResult;
import www.wmx.com.xssc.domain.vo.extract.ExtractPatent;
import www.wmx.com.xssc.domain.vo.extract.request.PatentRequest;
import www.wmx.com.xssc.domain.vo.request.RequestPicture;
import www.wmx.com.xssc.domain.vo.response.ResponsePicture;
import www.wmx.com.xssc.service.fj.IRbtScfjMbService;
import www.wmx.com.xssc.service.fj.IZtComUploadFileOriginService;
import www.wmx.com.xssc.service.fj.IZtComUploadFileService;
import www.wmx.com.xssc.service.jcyjj.IRbtKjjlJcyjjFjxxService;
import www.wmx.com.xssc.service.jcyjj.IRbtKjjlJcyjjJbxxService;
import www.wmx.com.xssc.service.jsfmj.IRbtKjjlJsfmjFjxxService;
import www.wmx.com.xssc.service.kjjbj.IRbtKjjlKjjbjFjxxService;
import www.wmx.com.xssc.util.common.MbReadUtil;
import www.wmx.com.xssc.util.common.NameConvertUtil;
import www.wmx.com.xssc.util.common.WcrReadUtil;
import www.wmx.com.xssc.util.enumUtil.CgType;
import www.wmx.com.xssc.util.enumUtil.CgjlType;
import www.wmx.com.xssc.util.pdf.PDF;
import www.wmx.com.xssc.util.time.DateFormatterUtil;
import www.wmx.com.xssc.util.tptq.ImageExtractionUtil;

import javax.annotation.Resource;
import java.io.IOException;
import java.io.InputStream;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import static www.wmx.com.xssc.xm.Similarity.pinyinSimilarity;

/**
 * @author Zhenyao.Diao
 * @create 2024/9/27 13:43
 * @description 通用专利解析类工具
 */

@Data
@Slf4j
@Component
public class PatentProcessUtil {

    /**
     * 列举类型所有的成果奖励的基本信息业务类：
     */
    @Resource(description = "基础研究奖的基本信息：")
    private IRbtKjjlJcyjjJbxxService jcyjjJbxxService;

    @Resource
    private MbReadUtil mbReadUtil;
    /**
     * 所有当前年度的项目中涉及的研究人员和项目的信息：
     */
    @Resource
    private WcrReadUtil wcrReadUtil;

    @Resource(description = "附件的类型枚举")
    private IRbtScfjMbService scfjMbService;

    //论文附件的所有的类型和名称：
    List<RbtScfjMb> scfjJcyjjLWMbList;
    List<RbtScfjMb> scfjKjjbjjLWMbList;
    List<RbtScfjMb> scfjJsfmjLWMbList;

    @Resource(description = "基础研究附件信息")
    private IRbtKjjlJcyjjFjxxService jcyjjFjxxService;

    @Resource(description = "技术发明奖附件信息")
    private IRbtKjjlJsfmjFjxxService jsfmjFjxxService;

    @Resource(description = "科技进步奖附件信息")
    private IRbtKjjlKjjbjFjxxService kjjbjFjxxService;

    @Resource
    private IZtComUploadFileService uploadFileService;
    @Resource
    private IZtComUploadFileOriginService uploadFileOriginService;

    @Resource(description = "论文图片提取工具")
    private ImageExtractionUtil imageExtractionUtil;

    // 作者排名：
    private RbtKjjlMbJcyjRank kjjlMbJcyjRank;
    //contains:   0、1、2
    private RbtKjjlMbTy rbtKjjlMbTyLW;
    // 基础研究奖根据等级要求论文的信息：
    private List<RbtKjjlMbJcyjj> kjjlMbJcyjjsList;
    private static final Pattern pattern = Pattern.compile("[\\u4e00-\\u9fa5]+");
    private static final DateTimeFormatter DATE_FORMAT = DateTimeFormatter.ofPattern("yyyy-MM-dd");

    private String basePath;

    public void init() {
        this.mbReadUtil.init();
        this.scfjJcyjjLWMbList = scfjMbService.lambdaQuery()
                .eq(RbtScfjMb::getYwlx, "基础研究奖")
                .eq(RbtScfjMb::getWjlx, "知识产权证明").list();
        this.scfjKjjbjjLWMbList = scfjMbService.lambdaQuery()
                .eq(RbtScfjMb::getYwlx, "科技进步奖")
                .eq(RbtScfjMb::getWjlx, "知识产权证明").list();
        this.scfjJsfmjLWMbList = scfjMbService.lambdaQuery()
                .eq(RbtScfjMb::getYwlx, "技术发明奖")
                .eq(RbtScfjMb::getWjlx, "知识产权证明").list();
        this.kjjlMbJcyjRank = this.mbReadUtil.getKjjlMbJcyjRank();
        this.kjjlMbJcyjjsList = this.mbReadUtil.getKjjlMbJcyjjsList();
        List<RbtKjjlMbTy> kjjlMbTyList = this.mbReadUtil.getKjjlMbTyList();
        for (RbtKjjlMbTy mbTy : kjjlMbTyList) {
            if (mbTy.getId().equals(CgType.ZL.getCode())) {
                this.rbtKjjlMbTyLW = mbTy;
                break;
            }
        }

        try {
            Properties properties = new Properties();
            // 读取my.properties配置文件到输入流中
            InputStream inputStream = PDF.class.getResourceAsStream("/config.properties");
            // 从输入流中加载属性列表
            properties.load(inputStream);
            this.basePath = properties.getProperty("file.upload.path");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 获取专利相关附件的文件路径
     *
     * @param patentRequest
     * @return
     */
    public String getPatentPath(PatentRequest patentRequest) {
        String path = null;
        String FJID = null;
        if (patentRequest.getCgjlType() == CgjlType.JCYJJ.getCode()) {
            RbtKjjlJcyjjFjxx jcyjjFjxx = jcyjjFjxxService.lambdaQuery()
                    .eq(RbtKjjlJcyjjFjxx::getKjjlJcyjjId, patentRequest.getJbxxID())
                    .eq(RbtKjjlJcyjjFjxx::getWjlx, "知识产权证明")
                    .eq(RbtKjjlJcyjjFjxx::getWjmc, "专利-关键页")
                    .one();
            if (jcyjjFjxx == null) {
                return null;
            }
            FJID = jcyjjFjxx.getFjId();
        } else if (patentRequest.getCgjlType() == CgjlType.JSFMJ.getCode()) {
            RbtKjjlJsfmjFjxx jsfmjFjxx = jsfmjFjxxService.lambdaQuery()
                    .eq(RbtKjjlJsfmjFjxx::getKjjlJsfmjId, patentRequest.getJbxxID())
                    .eq(RbtKjjlJsfmjFjxx::getWjlx, "知识产权证明")
                    .eq(RbtKjjlJsfmjFjxx::getWjmc, "专利-关键页")
                    .one();
            if (jsfmjFjxx == null) {
                return null;
            }
            FJID = jsfmjFjxx.getFjId();
        } else if (patentRequest.getCgjlType() == CgjlType.KJJBJ.getCode()) {
            RbtKjjlKjjbjFjxx kjjbjFjxx = kjjbjFjxxService.lambdaQuery()
                    .eq(RbtKjjlKjjbjFjxx::getKjjlKjjbjId, patentRequest.getJbxxID())
                    .eq(RbtKjjlKjjbjFjxx::getWjlx, "知识产权证明")
                    .eq(RbtKjjlKjjbjFjxx::getWjmc, "专利-关键页")
                    .one();
            if (kjjbjFjxx == null) {
                return null;
            }
            FJID = kjjbjFjxx.getFjId();

        }
        ZtComUploadFile uploadFile = uploadFileService.lambdaQuery()
                .eq(ZtComUploadFile::getId, FJID)
                .one();
        if (uploadFile == null) {
            return null;
        }
        ZtComUploadFileOrigin uploadFileOrigin = uploadFileOriginService.lambdaQuery()
                .eq(ZtComUploadFileOrigin::getId, uploadFile.getFileMd5())
                .one();
        if (uploadFileOrigin == null || uploadFileOrigin.getFilePath().isEmpty()) {
            return null;
        }
        path = uploadFileOrigin.getFilePath();
        if(!ImageExtractionUtil.isImageFile(path,basePath)){
            return null;
        }
        return this.basePath + path;
    }


    public ResponsePicture extractPicture(PatentRequest patentRequest) {
        RequestPicture requestPicture = new RequestPicture();
        requestPicture.setFilePath(patentRequest.getFilePath());
        ResponsePicture responsePicture = null;
        try {
            responsePicture = imageExtractionUtil.sendFormPost(requestPicture);
        } catch (Exception e) {
            log.error(e.getMessage());
        }
        return responsePicture;
    }

    public BaseMatchResult matchProcess(PatentRequest patentRequest) {
        //首先处理附件截图部分的具体地址信息：
        String patentPath = getPatentPath(patentRequest);
//        System.out.println("patentPath = " + patentPath);
        patentRequest.setFilePath(patentPath);
//        patentRequest.setFilePath("/root/OCR_Application/ocr_test_images/test1.png");//测试用路径
//        patentRequest.setFilePath("/home/user/workspace/test1.png");//测试用路径
        //作者排名
        BaseMatchResult result = new BaseMatchResult();
        List<String> failReason = new ArrayList<>();
        LocalDateTime xmBeginTimeEnroll = patentRequest.getXmBeginTime();
        LocalDateTime xmEndTimeEnroll = patentRequest.getXmEndTime();
        if(patentPath!=null) {
            ResponsePicture responsePicture = extractPicture(patentRequest);
            if(responsePicture!= null) {
                patentRequest.setPlainText(responsePicture.getData());
            }
        }else {
            failReason.add("专利-关键页图片不存在请重新上传");
        }
        //这是从论文中提取出来的内容：
        List<String> fmrList = null;
        if(patentPath!=null) {
            ExtractPatent extractPatent = processPatent(patentRequest.getPlainText());
            if(extractPatent!=null && extractPatent.getFmr()!=null && !extractPatent.getFmr().isEmpty() ) {
                fmrList = extractPatent.getFmr();
                patentRequest.setFmrList(fmrList);
            }
            if(extractPatent!=null && extractPatent.getSqrq()!=null) {
                patentRequest.setSqr(extractPatent.getSqrq().toLocalDate());
            }
        }
        boolean fmrMatch = false;
        boolean dateMatch = false;
        // 1.发明人的审查
        if(patentPath!=null && patentRequest.getFmrList()!=null && !patentRequest.getFmrList().isEmpty()) {
            fmrMatch = fmrMatch(fmrList, patentRequest);
        }
        //2、时间的审查：
        if(patentPath!=null && patentRequest.getSqr()!=null) {
            dateMatch = dateMatch(xmBeginTimeEnroll, xmEndTimeEnroll, patentRequest);
        }
        //3. 附件的审查：
        List<String> failReasonFJ = FJCheck(patentRequest);

        if (patentPath!=null && patentRequest.getFmrList()!=null && !patentRequest.getFmrList().isEmpty() && !fmrMatch) {
            failReason.add("完成人不匹配： " + "项目完成人中的任意一位" + " 并非是专利发明人中的一员");
        }
        if (patentPath!=null && patentRequest.getSqr()!=null && !dateMatch) {
            failReason.add("时间不匹配： " + patentRequest.getSqr().format(DATE_FORMAT) + " 专利申请时间并未在项目起始时间段内");
        }
        if (failReasonFJ != null && failReasonFJ.size() > 0) {
            failReason.addAll(failReasonFJ);
        }
        result.setFailReason(failReason);
        return result;
    }

    // 专利附件的审查
    public List<String> FJCheck(PatentRequest patentRequest) {
        List<String> failReason = new ArrayList<>();
        if (patentRequest.getCgjlType() == CgjlType.JCYJJ.getCode()) {
            for (RbtScfjMb scfjMb : scfjJcyjjLWMbList) {
                List<RbtKjjlJcyjjFjxx> fjxx = jcyjjFjxxService.lambdaQuery()
                        .eq(RbtKjjlJcyjjFjxx::getKjjlJcyjjId, patentRequest.getJbxxID())
                        .eq(RbtKjjlJcyjjFjxx::getWjmc, scfjMb.getWjmc())
                        .eq(RbtKjjlJcyjjFjxx::getWjlx, "知识产权证明")
                        .list();
                if (fjxx == null || fjxx.isEmpty()) {
                    failReason.add("知识产权证明缺少附件:  " + scfjMb.getWjmc() + " ");
                }
            }
        } else if (patentRequest.getCgjlType() == CgjlType.JSFMJ.getCode()) {
            for (RbtScfjMb scfjMb : scfjJsfmjLWMbList) {
                List<RbtKjjlJsfmjFjxx> fjxx = jsfmjFjxxService.lambdaQuery()
                        .eq(RbtKjjlJsfmjFjxx::getKjjlJsfmjId, patentRequest.getJbxxID())
                        .eq(RbtKjjlJsfmjFjxx::getWjmc, scfjMb.getWjmc())
                        .eq(RbtKjjlJsfmjFjxx::getWjlx, "知识产权证明")
                        .list();
                if (fjxx == null || fjxx.isEmpty()) {
                    failReason.add("知识产权证明缺少附件:  " + scfjMb.getWjmc() + " ");
                }
            }
        } else if (patentRequest.getCgjlType() == CgjlType.KJJBJ.getCode()) {
            for (RbtScfjMb scfjMb : scfjKjjbjjLWMbList) {
                List<RbtKjjlKjjbjFjxx> fjxx = kjjbjFjxxService.lambdaQuery()
                        .eq(RbtKjjlKjjbjFjxx::getKjjlKjjbjId, patentRequest.getJbxxID())
                        .eq(RbtKjjlKjjbjFjxx::getWjmc, scfjMb.getWjmc())
                        .eq(RbtKjjlKjjbjFjxx::getWjlx, "知识产权证明")
                        .list();
                if (fjxx == null || fjxx.isEmpty()) {
                    failReason.add("知识产权证明缺少附件:  " + scfjMb.getWjmc() + " ");
                }
            }
        }
        return failReason;
    }


    // 验证发明人是否是完成人中的一员：
    public boolean fmrMatch(List<String> fmrList, PatentRequest patentRequest) {
        List<WcryShortXM> wcryShortXMList = wcrReadUtil.getWcryFilterByTypeAndId(patentRequest.getCgjlType(), patentRequest.getJbxxID());
        if (wcryShortXMList == null || wcryShortXMList.isEmpty()) {
            return false;
        }
        for (String name : fmrList) {
            name = name.replaceAll(" ", "");
            String pinyinName = NameConvertUtil.convertToPinyin(name);
            for (WcryShortXM wcryShortXM : wcryShortXMList) {
                String enrollName = NameConvertUtil.convertToPinyin(wcryShortXM.getXm().replaceAll(" ", ""));
                double similarity = pinyinSimilarity(pinyinName, enrollName);
                if (pinyinName.equals(enrollName) || similarity >= 0.8) {
                    return true;
                }
            }
        }
        return false;
    }

    // 专利申请时间的审查：
    public boolean dateMatch(LocalDateTime begin, LocalDateTime end, PatentRequest patentRequest) {
        LocalDateTime fbsj = patentRequest.getSqr().atStartOfDay();
        return fbsj.isAfter(begin) && fbsj.isBefore(end);
    }


    public ExtractPatent processPatent(String request) {
        request = request.replaceAll(":", "：");
        String regex = "\\d+";
        Pattern pattern = Pattern.compile(regex);
        ExtractPatent response = new ExtractPatent();
        //申请号：
        int indexSQH = -1;
        int endIndexSQH = -1;
        if(request.indexOf("申请号：")!=-1) {
            indexSQH = request.indexOf("申请号：") + 4;
            endIndexSQH = request.indexOf("\n", indexSQH);
        }
        StringBuilder digits = null;
        if(indexSQH!=-1 && endIndexSQH!=-1  && endIndexSQH > indexSQH) {
            Matcher matcher = pattern.matcher(request.substring(indexSQH, endIndexSQH).trim());
            digits = new StringBuilder();
            while (matcher.find()) {
                digits.append(matcher.group());
            }
        }
        //申请日：
        int indexSQR;
        int endIndexSQR;
        LocalDateTime sqrq = null;
        if(request.indexOf("申请日：")!=-1) {
            indexSQR = request.indexOf("申请日：") + 4;
            endIndexSQR = request.indexOf("\n", indexSQR);
            if(indexSQR!=-1 && endIndexSQR!=-1 && endIndexSQR>indexSQR) {
                sqrq = DateFormatterUtil.StrToLocalDateTime(request.substring(indexSQR, endIndexSQR).trim());
            }
        }
         //发明人：
        int indexFMR;
        int endIndexFMR;
        List<String> fmrList = null;
        if(request.indexOf("发明人：")!=-1) {
            indexFMR = request.indexOf("发明人：") + 4;
            endIndexFMR = request.indexOf("\n", indexFMR);
            if(endIndexFMR!=-1 && endIndexFMR>indexFMR) {
                String fmrStr = request.substring(indexFMR, endIndexFMR);
                String[] fmrSplit = fmrStr.split("，,");
                fmrList = new ArrayList<>();
                for (String s : fmrSplit) {
                    fmrList.add(s.trim());
                }
            }
        }
        //发明创造名称：
        int indexFMCZMC;
        int endIndexFMCZMC;
        String fmczmcStr = null;
        if(request.indexOf("发明创造名称：")!=-1) {
             indexFMCZMC = request.indexOf("发明创造名称：") + 7;
             endIndexFMCZMC = request.indexOf("\n", indexFMCZMC);
             if(endIndexFMCZMC>indexFMCZMC) {
                 fmczmcStr = request.substring(indexFMCZMC, endIndexFMCZMC).trim();
             }
        }

        response.setZlh(digits!=null ? digits.toString() : null);
        response.setSqrq(sqrq);
        response.setFmr(fmrList);
        response.setZlmc(fmczmcStr);
        return response;
    }

//    public static void main(String[] args) {
//        String request = "国家知识产权局\n" +
//                "发文日：\n" +
//                "100033\n" +
//                "北京市金融街35号国际企业大厦A座16层北京三友知识产权代理\n" +
//                "有限公司\n" +
//                "王首峰(010-62300800)\n" +
//                "2023年12月28日\n" +
//                "申请号：202311827873.5\n" +
//                "发文序号：2023122800898350\n" +
//                "专利申请受理通知书\n" +
//                "根据专利法第28条及其实施细则第38条、第39条的规定，申请人提出的专利申请已由国家知识产权局\n" +
//                "受理。现将确定的申请号、申请日等信息通知如下：\n" +
//                "申请号：2023118278735\n" +
//                "申请日：2023年12月27日\n" +
//                "申请人：中国石油天然气股份有限公司，中石油煤层气有限责任公司，中联煤层气国家工程研究中心有限责\n" +
//                "任公司\n" +
//                "发明人：李树新，沈天晶，李永洲，胡叶正，侯伟，陈小春，李星涛，黄旭日，陈沫，徐云贵，杨劲，吴勇，李翔，周璐\n" +
//                "发明创造名称：一种逆时聚焦算子更新计算方法及装置\n" +
//                "经核实，国家知识产权局确认收到文件如下：\n" +
//                "权利要求书1份2页.权利要求项数：10项\n" +
//                "说明书1份12页\n" +
//                "说明书附图1份3页\n" +
//                "说明书摘要1份1页\n" +
//                "专利代理委托书1份2页\n" +
//                "发明专利请求书1份6页\n" +
//                "实质审查请求书文件份数：1份\n" +
//                "申请方案卷号：GAI23CN06791\n" +
//                "提示：\n" +
//                "1.申请人收到专利申请受理通知书之后，认为其记载的内容与申请人所提交的相应内容不一致时，可以向国家知识产权局\n" +
//                "请求更正。\n" +
//                "2.申请人收到专利申请受理通知书之后，再向国家知识产权局办理各种手续时，\n" +
//                "请晰地写明申请号。\n" +
//                "知\n" +
//                "国\n" +
//                "审查员：黄瑞宏\n" +
//                "审查部\n" +
//                "传利审查业券章\n" +
//                "联系电话：010-62356655\n" +
//                "200101\n" +
//                "纸件申请，回函请寄：100088北京市海淀区蓟门桥西土城路6号国家知识产权局专利局受理处收\n" +
//                "2022.10\n" +
//                "电子申请，当通过专利业务办理系统以电子文件形式提交相关文件。除另有规定外，以纸件等其他形式提交的\n" +
//                "文件视为未提交。";
//        ExtractPatent extractPatent = new PatentProcessUtil().processPatent(request);
//        System.out.println(extractPatent);
//    }

}
